﻿// CSharp Editor Example with Code Completion
// Copyright (c) 2006, Daniel Grunwald
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
// 
// - Redistributions of source code must retain the above copyright notice, this list
//   of conditions and the following disclaimer.
// 
// - Redistributions in binary form must reproduce the above copyright notice, this list
//   of conditions and the following disclaimer in the documentation and/or other materials
//   provided with the distribution.
// 
// - Neither the name of the ICSharpCode team nor the names of its contributors may be used to
//   endorse or promote products derived from this software without specific prior written
//   permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &AS IS& AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using DigitalRune.Windows.TextEditor;
using DigitalRune.Windows.TextEditor.Completion;
using Zove.Runtime.Core;
using Zove.Runtime.Core.Zoom;

namespace Zove.Modeling.Editor
{
    internal class CodeCompletionProvider : ICompletionDataProvider
    {
        private readonly string lastToken;
       
        private readonly Form1 mainForm;
        
        private ZoomClass curr;


        public CodeCompletionProvider(Form1 mainForm)
        {
            this.mainForm = mainForm;
        }

        public CodeCompletionProvider(Form1 mainForm, string lastToken) : this(mainForm)
        {
            this.lastToken = lastToken;
        }

        public string PreSelection
        {
            get { return null; }
        }

        #region ICompletionDataProvider Members

        public ImageList ImageList
        {
            get { return mainForm.imageList1; }
        }

        public int DefaultIndex
        {
            get { return -1; }
        }

        public CompletionDataProviderKeyResult ProcessKey(char key)
        {
            if (char.IsLetterOrDigit(key) || key == '_')
            {
                return CompletionDataProviderKeyResult.NormalKey;
            }
                return CompletionDataProviderKeyResult.InsertionKey;
        }

        /// <summary>
        /// Called when entry should be inserted. Forward to the insertion action of the completion data.
        /// </summary>
        public bool InsertAction(ICompletionData data, TextArea textArea, int insertionOffset, char key)
        {
            textArea.Caret.Position = textArea.Document.OffsetToPosition(insertionOffset);
            return data.InsertAction(textArea, key);
        }

        public ICompletionData[] GenerateCompletionData(string fileName, TextArea textArea, char charTyped)
        {
            // We can return code-completion items like this:

            //return new ICompletionData[] {
            //	new DefaultCompletionData("Text", "Description", 1)
            //};

            var data = new List<DefaultCompletionData>();
            ZoomLanguageNature languageNature = new ZoomLanguageNature();
            if (curr == null)
            {
                curr = languageNature.ClassLoader.LoadFromSource(
                    textArea.Text);
            }

            string[] instances = lastToken.Split('.');
            string instance = instances[instances.Length - 1];
            foreach (ZoomVariable var in curr.Variables)
            {
                if (var.Name == instance)
                {
                    curr = languageNature.ClassLoader.LoadByClassName(
                        var.Type);
                }
            }

            foreach (ZoomVariable var in curr.Variables)
            {
                data.Add(new DefaultCompletionData(var.Type, var.Type, 0));
            }

            return data.ToArray();
        }

        string ICompletionDataProvider.PreSelection
        {
            get { throw new NotImplementedException(); }
            set { throw new NotImplementedException(); }
        }

        #endregion
    }
}